

qc()

function qc(){
  const QCYSDK = (function () {
    function QCYSDK(appKey, appSecret) {
      http.__okhttp__.setMaxRetries(0);
      http.__okhttp__.setTimeout(10 * 1000);
      this.event = events.emitter();

      this.debug = true;
      this._lib_version = "v1.10";
      this._protocol = "http";
      this._host = "www.7ccccccc.com"
      this._device_id = this.getDeviceID();

      this._retry_count = 9;
      this._appKey = appKey;
      this._appSecret = appSecret;
      this._card = null;

      this._username = null;
      this._password = null;
      this._token = null;

      this.is_trial = false;
      this.login_result = {
        "card_type": "",
        "expires": "",
        "expires_ts": 0,
        "config": "",
      };

      this._auto_heartbeat = true;  // 是否自动开启心跳任务
      this._heartbeat_gap = 600 * 1000; // 默认600秒
      this._heartbeat_task = null;
      this._heartbeat_ret = { "code": -9, "message": "还未开始验证" };
      this._prev_nonce = null;
    }
    QCYSDK.prototype.SetCard = function (card) {
      this._card = card.trim();
    }
    QCYSDK.prototype.SetUser = function (username, password) {
      this._username = username.trim();
      this._password = password;
    }
    QCYSDK.prototype.MD5 = function (str) {
      try {
        let digest = java.security.MessageDigest.getInstance("md5");
        let result = digest.digest(new java.lang.String(str).getBytes("UTF-8"));
        let buffer = new java.lang.StringBuffer();
        for (let index = 0; index < result.length; index++) {
          let b = result[index];
          let number = b & 0xff;
          let str = java.lang.Integer.toHexString(number);
          if (str.length == 1) {
            buffer.append("0");
          }
          buffer.append(str);
        }
        return buffer.toString();
      } catch (error) {
        alert(error);
        return "";
      }
    }
    /* 通用 */
    QCYSDK.prototype.GetHeartbeatResult = function () {
      return this._heartbeat_ret;
    }
    QCYSDK.prototype.GetTimeRemaining = function () {
      let g = this.login_result.expires_ts - this.getTimestamp();
      if (g < 0) {
        return 0;
      }
      return g;
    }
    QCYSDK.prototype.getDeviceID = function () {
      let id = device.serial;
      if (id == null || id == "" || id == "unknown") {
        id = device.getAndroidId();
      }
      if (id == null || id == "" || id == "unknown") {
        id = device.getIMEI();
      }
      return id;
    }
    /* 卡密相关 *//*卡密登录功能*/
    QCYSDK.prototype.CardLogin = function () {  // 卡密登录
      if (!this._card) {
        return { "code": -4, "message": "请先设置卡密" };
      }
      let method = "POST";
      let path = "/v1/card/login";
      let data = { "card": this._card, "device_id": this._device_id };
      let ret = this.Request(method, path, data);
      if (ret.code == 0) {
        this._token = ret.result.token;
        this.login_result = ret.result;
        if (this._auto_heartbeat) {
          //调用心跳
          this._startCardHeartheat();
        }
      }
      return ret;
    }
    /*卡密心跳*/
    QCYSDK.prototype.CardHeartbeat = function () {  // 卡密心跳，默认会自动调用
      if (!this._token) {
        return { "code": -2, "message": "请在卡密登录成功后调用" };
      }
      let method = "POST";
      let path = "/v1/card/heartbeat";
      let data = { "card": this._card, "token": this._token };
      let ret = this.Request(method, path, data);
      if (ret.code == 0) {
        this.login_result.expires = ret.result.expires;
        this.login_result.expires_ts = ret.result.expires_ts;
      }
      return ret;
    }
    QCYSDK.prototype._startCardHeartheat = function () {  // 开启卡密心跳任务
      if (this._heartbeat_task) {
        this._heartbeat_task.interrupt();
        this._heartbeat_task = null;
      }
      this._heartbeat_task = threads.start(function () {
        setInterval(function () { }, 10000);
      });
      this._heartbeat_ret = this.CardHeartbeat();
      this._heartbeat_task.setInterval((self) => {
        self._heartbeat_ret = self.CardHeartbeat();
        if (self._heartbeat_ret.code != 0) {
          self.event.emit("heartbeat_failed", self._heartbeat_ret);
        }
      }, this._heartbeat_gap, this);
      this._heartbeat_task.setInterval((self) => {
        if (self.GetTimeRemaining() == 0) {
          8
          self.event.emit("heartbeat_failed", { "code": 10210, "message": "卡密已过期！" });
        }
      }, 1000, this);
    }
    QCYSDK.prototype.CardRecharge = function (card, useCard) { // 以卡充卡
      let method = "POST";
      let path = "/v1/card/recharge";
      let data = { "card": card, "useCard": useCard };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.CardLogout = function (token) {  // 卡密退出登录
      this._heartbeat_ret = { "code": -9, "message": "还未开始验证" };
      if (this._heartbeat_task) { // 结束心跳任务
        this._heartbeat_task.interrupt();
        this._heartbeat_task = null;
      }
      if (!token) {
        return { "code": 0, "message": "OK" };
      }
      let method = "POST";
      let path = "/v1/card/logout";
      let data = { "card": this._card, "token": token };
      let ret = this.Request(method, path, data);
      // 清理
      this._token = null;
      this.login_result = {
        "card_type": "",
        "expires": "",
        "expires_ts": 0,
        "config": "",
      };
      return ret;
    }
    QCYSDK.prototype.CardUnbindDevice = function () { // 卡密解绑设备，需开发者后台配置
      let method = "POST";
      let path = "/v1/card/unbind_device";
      let data = { "card": this._card, "device_id": this._device_id };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.SetCardUnbindPassword = function (password) { // 自定义设置解绑密码
      if (!this._token) {
        return { "code": -2, "message": "请在卡密登录成功后调用" };
      }
      let method = "POST";
      let path = "/v1/card/unbind_password";
      let data = { "card": this._card, "password": password, "token": this._token };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.CardUnbindDeviceByPassword = function (password) { // 用户通过解绑密码解绑设备
      let method = "POST";
      let path = "/v1/card/unbind_device/by_password";
      let data = { "card": this._card, "password": password };
      return this.Request(method, path, data);
    }
    /* 用户相关 */
    QCYSDK.prototype.UserRegister = function (username, password, card) {  // 用户注册（通过卡密）
      let method = "POST";
      let path = "/v1/user/register";
      let data = { "username": username, "password": password, "card": card, "device_id": this._device_id };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.UserLogin = function () {  // 用户账号登录
      if (!this._username || !this._password) {
        return { "code": -4, "message": "请先设置用户账号密码" };
      }
      let method = "POST";
      let path = "/v1/user/login";
      let data = { "username": this._username, "password": this._password, "device_id": this._device_id };
      let ret = this.Request(method, path, data);
      if (ret.code == 0) {
        this._token = ret.result.token;
        this.login_result = ret.result;
        if (this._auto_heartbeat) {
          this._startUserHeartheat();
        }
      }
      return ret;
    }
    QCYSDK.prototype.UserHeartbeat = function () {  // 用户心跳，默认会自动开启
      if (!this._token) {
        return { "code": -2, "message": "请在用户登录成功后调用" };
      }
      let method = "POST";
      let path = "/v1/user/heartbeat";
      let data = { "username": this._username, "token": this._token };
      let ret = this.Request(method, path, data);
      if (ret.code == 0) {
        this.login_result.expires = ret.result.expires;
        this.login_result.expires_ts = ret.result.expires_ts;
      }
      return ret;
    }
    QCYSDK.prototype._startUserHeartheat = function () {  // 开启用户心跳任务
      if (this._heartbeat_task) {
        this._heartbeat_task.interrupt();
        this._heartbeat_task = null;
      }
      this._heartbeat_task = threads.start(function () {
        setInterval(function () { }, 10000);
      });
      this._heartbeat_ret = this.UserHeartbeat();

      this._heartbeat_task.setInterval((self) => {
        self._heartbeat_ret = self.UserHeartbeat();
        if (self._heartbeat_ret.code != 0) {
          self.event.emit("heartbeat_failed", self._heartbeat_ret);
        }
      }, this._heartbeat_gap, this);

      this._heartbeat_task.setInterval((self) => {
        if (self.GetTimeRemaining() == 0) {
          self.event.emit("heartbeat_failed", { "code": 10250, "message": "用户已到期！" });
        }
      }, 1000, this);
    }
    QCYSDK.prototype.UserLogout = function (token) {  // 用户退出登录
      this._heartbeat_ret = { "code": -9, "message": "还未开始验证" };
      if (this._heartbeat_task) { // 结束心跳任务
        this._heartbeat_task.interrupt();
        this._heartbeat_task = null;
      }
      if (!token) {
        return { "code": 0, "message": "OK" };
      }
      let method = "POST";
      let path = "/v1/user/logout";
      let data = { "username": this._username, "token": token };
      let ret = this.Request(method, path, data);
      // 清理
      this._token = null;
      this.login_result = {
        "card_type": "",
        "expires": "",
        "expires_ts": 0,
        "config": "",
      };
      return ret;
    }
    QCYSDK.prototype.UserChangePassword = function (username, password, newPassword) {  // 用户修改密码
      let method = "POST";
      let path = "/v1/user/password";
      let data = { "username": username, "password": password, "newPassword": newPassword };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.UserRecharge = function (username, card) { // 用户通过卡密充值
      let method = "POST";
      let path = "/v1/user/recharge";
      let data = { "username": username, "card": card };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.UserUnbindDevice = function () { // 用户解绑设备，需开发者后台配置
      let method = "POST";
      let path = "/v1/user/unbind_device";
      let data = { "username": this._username };
      return this.Request(method, path, data);
    }
    /* 配置相关 */
    QCYSDK.prototype.GetCardConfig = function () { // 获取卡密配置
      let method = "POST";
      let path = "/v1/card/config";
      let data = { "card": this._card };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.UpdateCardConfig = function (config) { // 更新卡密配置
      let method = "POST";
      let path = "/v1/card/config";
      let data = { "card": this._card, "config": config };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.GetUserConfig = function () { // 获取用户配置
      let method = "POST";
      let path = "/v1/user/config";
      let data = { "username": this._username };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.UpdateUserConfig = function (config) { // 更新用户配置
      let method = "POST";
      let path = "/v1/user/config";
      let data = { "username": this._username, "config": config };
      return this.Request(method, path, data);
    }
    /* 软件相关 */
    QCYSDK.prototype.GetSoftwareConfig = function () { // 获取软件配置
      let method = "POST";
      let path = "/v1/software/config";
      return this.Request(method, path, {});
    }
    QCYSDK.prototype.GetSoftwareNotice = function () { // 获取软件通知
      let method = "POST";
      let path = "/v1/software/notice";
      return this.Request(method, path, {});
    }
    QCYSDK.prototype.GetSoftwareVersion = function () { // 获取软件版本
      let method = "POST";
      let path = "/v1/software/latest_ver";
      return this.Request(method, path, {});
    }
    /* 试用功能 */
    QCYSDK.prototype.TrialLogin = function () {  // 试用登录
      let method = "POST";
      let path = "/v1/trial/login";
      let data = { "device_id": this._device_id };
      let ret = this.Request(method, path, data);
      if (ret.code == 0) {
        this.is_trial = true;
        this.login_result = ret.result;
        this._token = ret.result.token;
        if (this._auto_heartbeat) {
          this._startTrialHeartheat();
        }
      }
      return ret;
    }
    QCYSDK.prototype.TrialHeartbeat = function () {  // 试用心跳，默认会自动调用
      let method = "POST";
      let path = "/v1/trial/heartbeat";
      let data = { "device_id": this._device_id, "token": this._token };
      let ret = this.Request(method, path, data);
      if (ret.code == 0) {
        this.login_result.expires = ret.result.expires;
        this.login_result.expires_ts = ret.result.expires_ts;
      }
      return ret;
    }
    QCYSDK.prototype._startTrialHeartheat = function () {  // 开启试用心跳任务
      if (this._heartbeat_task) {
        this._heartbeat_task.interrupt();
        this._heartbeat_task = null;
      }
      this._heartbeat_task = threads.start(function () {
        setInterval(function () { }, 10000);
      });
      this._heartbeat_ret = this.TrialHeartbeat();
      this._heartbeat_task.setInterval((self) => {
        self._heartbeat_ret = self.TrialHeartbeat();
        if (self._heartbeat_ret.code != 0) {
          self.event.emit("heartbeat_failed", self._heartbeat_ret);
        }
      }, this._heartbeat_gap, this);
      this._heartbeat_task.setInterval((self) => {
        if (self.GetTimeRemaining() == 0) {
          self.event.emit("heartbeat_failed", { "code": 10407, "message": "试用已到期！" });
        }
      }, 1000, this);
    }
    QCYSDK.prototype.TrialLogout = function () {  // 试用退出登录，没有http请求，只是清理本地记录
      this.is_trial = false;
      this._heartbeat_ret = { "code": -9, "message": "还未开始验证" };
      if (this._heartbeat_task) { // 结束心跳任务
        this._heartbeat_task.interrupt();
        this._heartbeat_task = null;
      }
      // 清理
      this._token = null;
      this.login_result = {
        "card_type": "",
        "expires": "",
        "expires_ts": 0,
        "config": "",
      };
      return { "code": 0, "message": "OK" };
    }
    /* 高级功能 */
    QCYSDK.prototype.GetRemoteVar = function (key) { // 获取远程变量
      let method = "POST";
      let path = "/v1/af/remote_var";
      let data = { "varName": key, "token": this._token };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.GetRemoteData = function (key) { // 获取远程数据
      let method = "POST";
      let path = "/v1/af/remote_data";
      let data = { "key": key, "token": this._token };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.CreateRemoteData = function (key, value) { // 创建远程数据
      let method = "POST";
      let path = "/v1/af/remote_data";
      let data = { "action": "create", "key": key, "value": value, "token": this._token };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.UpdateRemoteData = function (key, value) { // 修改远程数据
      let method = "POST";
      let path = "/v1/af/remote_data";
      let data = { "action": "update", "key": key, "value": value, "token": this._token };
      return this.Request(method, path, data);
    }
    QCYSDK.prototype.DeleteRemoteData = function (key) { // 删除远程数据
      let method = "POST";
      let path = "/v1/af/remote_data";
      let data = { "action": "delete", "key": key, "token": this._token };
      return this.Request(method, path, data);
    }

    QCYSDK.prototype.Request = function (method, path, params) {
      // 构建公共参数
      params["appKey"] = this._appKey;
      method = method.toUpperCase();
      let url = this._protocol + "://" + this._host + path
      let max_retries = this._retry_count;
      let retries_count = 0;

      let data = { "code": -1, "message": "连接服务器失败" };
      do {
        retries_count++;
        let sec = this.retry_fib(retries_count);
        delete params["sign"]
        params["nonce"] = this.genNonce();
        params["timestamp"] = this.getTimestamp();
        let ps = this.joinParams(params);
        let s = method + this._host + path + ps + this._appSecret;
        let sign = this.MD5(s);
        params["sign"] = sign;
        let resp, body;
        try {
          if (method === "GET") {
            resp = http.get(url + "?" + ps + "&sign=" + sign);
          } else {  // POST
            resp = http.post(url, params);
          }
          body = resp.body.string();
          data = JSON.parse(body);
          this._debug(method + '-' + path + ':', params, data);
          let crs = this.CheckRespSign(data);
          if (crs.code !== 0) {
            return crs;
          } else {
            return data;
          }
        } catch (error) {
          log("[*] request error: ", error, sec + "s后重试");
          this._debug(method + '-' + path + ':', params, body)
          sleep(sec * 1000);
        }
      } while (retries_count < max_retries);
      return data;
    }
    /*工具类*/
    QCYSDK.prototype.retry_fib = function (num) {
      if (num > 9) {
        return 34
      }
      let a = 0;
      let b = 1;
      for (let i = 0; i < num; i++) {
        let tmp = a + b;
        a = b
        b = tmp
      }
      return a
    }
    QCYSDK.prototype.genNonce = function () {
      const ascii_str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
      let tmp = '';
      for (let i = 0; i < 20; i++) {
        tmp += ascii_str.charAt(Math.round(Math.random() * ascii_str.length));
      }
      return this.MD5(this._device_id + this._prev_nonce + new Date().getTime() + tmp);
    }
    QCYSDK.prototype.getTimestamp = function () {
      try {
        let res = http.get("http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp");
        let data = res.data.json()
        return Math.floor(data["data"]["t"] / 1000);
      } catch (error) {
        return Math.floor(new Date().getTime() / 1000);
      }
    }
    QCYSDK.prototype.joinParams = function (params) {
      let ps = [];
      for (let k in params) {
        ps.push(k + "=" + params[k])
      }
      ps.sort()
      return ps.join("&")
    }
    QCYSDK.prototype.CheckRespSign = function (resp) {
      if (resp.code != 0 && resp.nonce === "" && resp.sign === "") {
        return resp
      }
      let ps = "";
      if (resp["result"]) {
        ps = this.joinParams(resp["result"]);
      }
      let s = resp["code"] + resp["message"] + ps + resp["nonce"] + this._appSecret;
      let sign = this.MD5(s);
      if (sign === resp["sign"]) {
        return { "code": 0, "message": "OK" };
      }
      return { "code": -99, "message": "CRS:签名校验失败" };
    }
    QCYSDK.prototype._debug = function (path, params, result) {
      if (this.debug) {
        //  console.log("\n" + path, "\nparams:", params, "\nresult:", result)/****?******* */
      }
    }
    return QCYSDK;
  })();

  /* 将QCYSDK.js文件中的代码复制粘贴到上面 */
  let qcysdk = new QCYSDK("eHU99eStB25wd82z0Z", "vv4A9r17lBETTNiUFW5CDGxsjoAJb353");
  qcysdk.debug = true; // 开发时建议开启debug，有详细输出
  qcysdk.SetCard("2JpJmZghdFtN3mjhXYrRsp5P3E9MU7GYVrxDzsj4");
  // 监听心跳失败事件
  qcysdk.event.on("heartbeat_failed", function (hret) {
    log("心跳失败，尝试重登...")
    sleep(2000);
    let login_ret = qcysdk.CardLogin();
    if (login_ret.code == 0) {
      log("重登成功");
    } else {
      toastLog(login_ret.message);  // 重登失败
      sleep(200);
      exit();  // 退出脚本
    }
  });

  // 当脚本正常或者异常退出时会触发exit事件
  events.on("exit", function () {
    qcysdk.CardLogout(); // 调用退出登录
    log("结束运行");
  });

  // 卡密登录
  // 登录成功后将自动启动一个线程发送心跳包，开发者只需监听心跳失败事件做处理就行了
  let login_ret = qcysdk.CardLogin();
  if (login_ret.code == 0) {
    // 登录成功，后面写你的业务代码


    log('剩余有效期' + parseInt(qcysdk.GetTimeRemaining() / 86400 + 1) + "天")
  } else {
    toast(login_ret.message);  // 登录失败的提示信息
  }

}